import React, { useCallback, useEffect, useMemo, useState } from "react";
import {
    Divider,
    Empty,
    Spin,
} from 'antd'
import './style.less'
import { ResultHeader } from "@/components/DataFlow/common/ResultHeader";
import { useCurrentNode } from "@/hooks/useCurrentNode";
import { useNodesData, useReactFlow } from "@xyflow/react";
import { RESULT_SHOW_MODE_DICT } from "@/constant/icons";
import { JoinResultField } from "./JoinResultField";
import { JoinResultData } from "./JoinResultData";
import { usePreviousNodes } from "@/hooks/usePreviousNodes";
import { randomUUID } from "@/utils/dataflow";
import { isEqual } from "lodash-es";
import { motion } from 'motion/react'

export const JoinResult = () => {
    const currentNode = useCurrentNode()
    const nodeData = useNodesData(currentNode?.id)
    const { updateNodeData } = useReactFlow()
    const [searchValue, setSearchValue] = useState('')
    const [showMode, setShowMode] = useState(RESULT_SHOW_MODE_DICT.field)
    const preNodes = usePreviousNodes(currentNode?.id)
    const leftNode = useNodesData(preNodes?.[0]?.id)
    const rightNode = useNodesData(preNodes?.[1]?.id)

    const allColumns = nodeData?.data?.allColumns
    const columns = nodeData?.data?.columns

    const setAllColumns = (allColumns) => {
        updateNodeData(currentNode?.id, { allColumns })
    }

    const setColumns = (columns) => {
        updateNodeData(currentNode?.id, { columns })
    }

    const initAllColumns = () => {
        // 处理左侧节点列
        const columns1 = leftNode?.data?.columns?.map(g => ({
            ...g,
            sourceColumnId: g.columnId,
            sourceColumnName: g.columnName,
            sourceComponentId: leftNode?.id,
            sourceComponentName: leftNode?.data?.label,
            sourceComponentType: leftNode?.type,
        })) ?? [];

        // 处理右侧节点列
        const columns2 = rightNode?.data?.columns?.map(g => ({
            ...g,
            sourceColumnId: g.columnId,
            sourceColumnName: g.columnName,
            sourceComponentId: rightNode?.id,
            sourceComponentName: rightNode?.data?.label,
            sourceComponentType: rightNode?.type,
        })) ?? [];

        // 合并两列数组
        const mergedColumns = [...columns1, ...columns2];

        // 处理重复ID
        const uniqueColumns = handleDuplicateColumns(mergedColumns);

        if (!isEqual(uniqueColumns, allColumns)) {
            setAllColumns(uniqueColumns)
        }
    };

    /**
     * 处理重复的columnId和columnName
     * @param columns 原始列数组
     * @returns 处理后的列数组
     */
    const handleDuplicateColumns = (columns) => {
        const idMap = new Map();    // 记录已存在的columnId
        const nameMap = new Map();  // 记录已存在的columnName

        return columns.map(column => {
            let newColumn = { ...column };

            // 处理重复columnId - 生成新UUID
            if (idMap.has(newColumn.columnId)) {
                newColumn = {
                    ...newColumn,
                    columnId: randomUUID(), // 生成无连字符的UUID
                    sourceColumnId: newColumn.columnId
                };
            } else {
                idMap.set(newColumn.columnId, true);
            }

            // 处理重复columnName - 添加后缀
            if (nameMap.has(newColumn.columnName)) {
                let counter = 1;
                let newName = `${newColumn.columnName}_${counter}`;

                while (nameMap.has(newName)) {
                    counter++;
                    newName = `${newColumn.columnName}_${counter}`;
                }

                newColumn = {
                    ...newColumn,
                    columnName: newName,
                    sourceColumnName: newName
                };
                nameMap.set(newName, true);
            } else {
                nameMap.set(newColumn.columnName, true);
            }

            return newColumn;
        });
    };

    useEffect(() => {
        if (leftNode && rightNode) {
            initAllColumns()
        }
    }, [leftNode, rightNode])

    const searchResult = useMemo(() => {
        if (!searchValue) return allColumns
        return allColumns?.filter(s => s.columnName?.indexOf(searchValue) > -1)
    }, [allColumns, searchValue])

    const handleSelectionChange = (items) => {
        // 将当前选中的项转换为Set以便快速查找
        const selectedNames = new Set(items);

        let finalColumns;

        if (searchValue) {
            // 当有搜索值时，我们需要:
            // 1. 保留不在searchResult中的现有列
            // 2. 更新在searchResult中的列（根据当前选择状态）

            // 获取searchResult中的所有列名
            const searchResultNames = new Set(
                searchResult?.map(col => col.columnId) || []
            );

            // 分为两部分处理：
            // 1. 保留不在searchResult中的现有列
            const columnsOutsideSearch = (columns || []).filter(
                col => !searchResultNames.has(col.columnId)
            );

            // 2. 处理searchResult中的列 - 只保留被选中的
            const columnsFromSearch = (searchResult || []).filter(
                col => selectedNames.has(col.columnId)
            );

            // 合并两部分
            finalColumns = [...columnsOutsideSearch, ...columnsFromSearch];
        } else {
            // 没有搜索值时，直接用所有选中的列
            finalColumns = allColumns?.filter(d => selectedNames.has(d.columnId)) || [];
        }
        // 更新节点数据
        updateNodeData(currentNode?.id, { columns: finalColumns });
    };

    const selectedRowKeys = useMemo(() => {
        return columns?.map(c => c.columnId)
    }, [columns])

    const handleChange = (row) => {
        const fieldMapper = (field) => {
            return field.columnId === row.columnId ? { ...row } : field
        }
        const updatedAllColumns = allColumns?.map(fieldMapper)
        const updatedColumns = columns?.map(fieldMapper)
        updateNodeData(currentNode?.id, { allColumns: updatedAllColumns, columns: updatedColumns })
    }

    const renderContent = () => {
        if (showMode === RESULT_SHOW_MODE_DICT.data) {
            return <motion.div
                key="data"
                initial={{ opacity: 0, x: 10 }}
                animate={{ opacity: 1, x: 0 }}
                exit={{ opacity: 0, x: -10 }}
                transition={{ duration: 0.2 }}
            >
                <JoinResultData />
            </motion.div >
        } else if (showMode === RESULT_SHOW_MODE_DICT.field) {
            return <motion.div
                key="field"
                initial={{ opacity: 0, x: 10 }}
                animate={{ opacity: 1, x: 0 }}
                exit={{ opacity: 0, x: -10 }}
                transition={{ duration: 0.2 }}
            >
                <JoinResultField datasource={searchResult} selectedRowKeys={selectedRowKeys}
                    onSelectionChange={handleSelectionChange} onChange={handleChange}
                />
            </motion.div>
        } else {
            return <motion.div
                key="default-empty"
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                exit={{ opacity: 0 }}
                transition={{ duration: 0.2 }}
            >
                <Empty />
            </motion.div>
        }
    }

    return (
        <div className="join-result-container">
            <ResultHeader info="关联结果"
                total={allColumns?.length ?? 0}
                select={columns?.length}
                mode={showMode}
                onChange={setShowMode}
                onSearch={setSearchValue}
            />
            <Divider style={{ margin: '8px 0' }} />
            <div className="join-result-table">
                {
                    renderContent()
                }
            </div>
        </div>
    );
};